// ICoder.h

using System;
using System.IO;

namespace SevenZip
{
   /// <summary>
   /// The exception that is thrown when an error in input stream occurs during decoding.
   /// </summary>
   internal class DataErrorException : ApplicationException
   {
      public DataErrorException() : base("Data Error")
      {
      }
   }

   /// <summary>
   /// The exception that is thrown when the value of an argument is outside the allowable range.
   /// </summary>
   internal class InvalidParamException : ApplicationException
   {
      public InvalidParamException() : base("Invalid Parameter")
      {
      }
   }

   /// <summary>
   /// 
   /// </summary>
   public interface ICodeProgress
   {
      /// <summary>
      /// Callback progress.
      /// </summary>
      /// <param name="inSize">
      /// input size. -1 if unknown.
      /// </param>
      /// <param name="outSize">
      /// output size. -1 if unknown.
      /// </param>
      void SetProgress(Int64 inSize, Int64 outSize);
   } ;

   /// <summary>
   /// 
   /// </summary>
   public interface ICoder
   {
      /// <summary>
      /// Codes streams.
      /// </summary>
      /// <param name="inStream">
      /// input Stream.
      /// </param>
      /// <param name="outStream">
      /// output Stream.
      /// </param>
      /// <param name="inSize">
      /// input Size. -1 if unknown.
      /// </param>
      /// <param name="outSize">
      /// output Size. -1 if unknown.
      /// </param>
      /// <param name="progress">
      /// callback progress reference.
      /// </param>
      /// <exception cref="SevenZip.DataErrorException">
      /// if input stream is not valid
      /// </exception>
      void Code(Stream inStream, Stream outStream,
                Int64 inSize, Int64 outSize, ICodeProgress progress);
   } ;

   /*
	public interface ICoder2
	{
		 void Code(ISequentialInStream []inStreams,
				const UInt64 []inSizes, 
				ISequentialOutStream []outStreams, 
				UInt64 []outSizes,
				ICodeProgress progress);
	};
  */

   /// <summary>
   /// Provides the fields that represent properties idenitifiers for compressing.
   /// </summary>
   public enum CoderPropID
   {
      /// <summary>
      /// Specifies size of dictionary.
      /// </summary>
      DictionarySize = 0x400,
      /// <summary>
      /// Specifies size of memory for PPM*.
      /// </summary>
      UsedMemorySize,
      /// <summary>
      /// Specifies order for PPM methods.
      /// </summary>
      Order,
      /// <summary>
      /// Specifies number of postion state bits for LZMA (0 &lt;= x &lt;= 4).
      /// </summary>
      PosStateBits = 0x440,
      /// <summary>
      /// Specifies number of literal context bits for LZMA (0 &lt;= x &lt;= 8).
      /// </summary>
      LitContextBits,
      /// <summary>
      /// Specifies number of literal position bits for LZMA (0 &lt;= x &lt;= 4).
      /// </summary>
      LitPosBits,
      /// <summary>
      /// Specifies number of fast bytes for LZ*.
      /// </summary>
      NumFastBytes = 0x450,
      /// <summary>
      /// Specifies match finder. LZMA: "BT2", "BT4" or "BT4B".
      /// </summary>
      MatchFinder,
      /// <summary>
      /// Specifies number of passes.
      /// </summary>
      NumPasses = 0x460,
      /// <summary>
      /// Specifies number of algorithm.
      /// </summary>
      Algorithm = 0x470,
      /// <summary>
      /// Specifies multithread mode.
      /// </summary>
      MultiThread = 0x480,
      /// <summary>
      /// Specifies mode with end marker.
      /// </summary>
      EndMarker = 0x490
   } ;

   /// <summary>
   /// 
   /// </summary>
   public interface ISetCoderProperties
   {
      /// <summary>
      /// Sets the coder properties.
      /// </summary>
      /// <param name="propIDs">The prop I ds.</param>
      /// <param name="properties">The properties.</param>
      void SetCoderProperties(CoderPropID[] propIDs, object[] properties);
   } ;

   /// <summary>
   /// 
   /// </summary>
   public interface IWriteCoderProperties
   {
      /// <summary>
      /// Writes the coder properties.
      /// </summary>
      /// <param name="outStream">The out stream.</param>
      void WriteCoderProperties(Stream outStream);
   }

   /// <summary>
   /// 
   /// </summary>
   public interface ISetDecoderProperties
   {
      /// <summary>
      /// Sets the decoder properties.
      /// </summary>
      /// <param name="properties">The properties.</param>
      void SetDecoderProperties(byte[] properties);
   }
}